import type { PageMetaDatum, PagesConfig, SubPageMetaDatum } from './config'
import { existsSync } from 'node:fs'

import { mkdir, writeFile as writeFile_ } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { normalizePath } from 'vite'

export interface IGenDeclaration extends PagesConfig {
  subPackages: SubPageMetaDatum[]
  pages: PageMetaDatum[]
}
export function genDeclaration(pageJson: IGenDeclaration, dtsPath: string) {
  const { subPackages, pages, tabBar } = pageJson

  const subPagesPath = subPackages.map((sub) => {
    return sub.pages.map(v => {
      if (typeof v === 'string') return ''
      return `"/${normalizePath(join(sub.root, v.path))}"`
    })
  }).flat().filter(Boolean)
  const tabsPagesPath = tabBar?.list?.map((v) => {
    return `"/${v!.pagePath}"`
  }) ?? []
  const allPagesPath = [...pages.filter(page => typeof page !== 'string' && !tabsPagesPath.includes(page.path)).map(v => `"/${v.path}"`), ...subPagesPath]
  const code = `/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by mui-vite-plugin

interface NavigateToOptions {
  url: ${allPagesPath.join(' |\n       ')};
}
interface RedirectToOptions extends NavigateToOptions {}

interface SwitchTabOptions {
  ${tabsPagesPath.length ? `url: ${tabsPagesPath.join(' | ')}` : ''}
}

type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;

declare interface Uni {
  navigateTo(options: UniNamespace.NavigateToOptions & NavigateToOptions): void;
  redirectTo(options: UniNamespace.RedirectToOptions & RedirectToOptions): void;
  switchTab(options: UniNamespace.SwitchTabOptions & SwitchTabOptions): void;
  reLaunch(options: UniNamespace.ReLaunchOptions & ReLaunchOptions): void;
}
`
  createFile(dtsPath, code)
}

async function createFile(p: string, tmp = '') {
  // 根据path 创建文件夹,如果中间任意一级路径不存在，则依次创建符合路径的文件夹层级
  const dirPath = dirname(p)

  try {
    // 检查目录是否存在，如果不存在则创建
    if (!existsSync(dirPath)) {
      console.log('目录不存在，正在创建...')
      await mkdir(dirPath, { recursive: true })
    }

    writeFile_(p, tmp, { flag: 'w' })
  }
  catch (error) {
    console.log(error)
  }
}
